% !Mode:: "TeX:UTF-8"

\chapter{系统实现}

\section{更新时间间隔缓存}
\begin{lstlisting}
  //全局变量
  Map<String,Integer> intervalMap = new HashMap<String,Integer>();

  //在新增信息的时候会判断map里是否为空，为空就插入，这是防止覆盖更改更新时间间隔操作。
  String insertMacAddress = allData.getMacAddress();
  Integer insertInterval = allData.getUpdateInterval();
  if(intervalMap.get(insertMacAddress) == null) {
      intervalMap.put(insertMacAddress, insertInterval);
  }
  Integer nowInterval = intervalMap.get(insertMacAddress);

  //更改更新时间间隔,在put中进行查找并更改.
  Integer tempInterval = intervalMap.get(macAddress);
  if(tempInterval != updateinterval)
  {
      intervalMap.remove(macAddress);
      intervalMap.put(macAddress,updateinterval);
  }
\end{lstlisting}

\section{新增设备信息}
\begin{lstlisting}
  //插入表equipment。在新增信息的时候，生成设备对象，同时对设备进行新增
  Equipment tempEquipment = new Equipment();
  tempEquipment.setMacAddress(allData.getMacAddress());
  tempEquipment.setRaspberryPiName(allData.getRaspberryPiName());
  int result = equipmentService.save(tempEquipment);
\end{lstlisting}

\section{AllDataController}
\begin{lstlisting}
  @RestController
  @RequestMapping(path="/allData")
  public class AllDataController {
      //注入 alldata sevice
      @Autowired
      private AllDataService allDataService;
      @Autowired
      private EquipmentService equipmentService;
      Map<String,Integer> intervalMap = new HashMap<String,Integer>();
  
      /**
       * 查询所有信息列表
       * @return
       */
      @RequestMapping(value = "/list",method = RequestMethod.GET)
      public List<AllData> getAllDatas(){
          return allDataService.findAllDataList();
      }
  
      @RequestMapping(value = "/equipment",method = RequestMethod.GET)
      public List<Equipment> getAllEquipment(){
          return equipmentService.findEquipmentList();
      }
  
      @RequestMapping(value = "/getEquipment/{macAddress}",method = RequestMethod.GET)
      public Equipment getEquipment(@PathVariable("macAddress") String macAddress){
          return equipmentService.findEquipment(macAddress);
      }
      /**
       * 通过时间戳timestamp查询一个设备的信息
       * @return
       */
      @RequestMapping(value = "/getByTimestamp/{timestamp}",method = RequestMethod.GET)
      public  AllData getDataByTimestamp(@PathVariable("timestamp") Integer timestamp){
          return allDataService.findAllDataByTimestamp(timestamp);
      }
  
      /**
       * 通过macAddress查询设备的信息
       * @return
       */
      @RequestMapping(value = "/getByMacAddress/{macAddress}",method = RequestMethod.GET)
      public List<AllData> getDataByMacAddress(@PathVariable("macAddress") String macAddress){
          return allDataService.findAllDataByMacAddress(macAddress);
      }
  
      /**
       * 查询某一设备某个时间段的信息
       * @param startTime
       * @param endTime
       * @return
       */
      //根据书写的时间到service里进行比较
      @RequestMapping(value = "/getByTimeBucket",method = RequestMethod.GET)
      public  List<AllData> getDataByTime(@RequestParam(name ="startTime") String startTime,@RequestParam(name ="endTime")String endTime){
          return allDataService.findAllDataByTimeBucket(startTime,endTime);
      }
  
      /**
       * 删除一个信息
       * @param timestamp
       * @return
       */
      @RequestMapping(value = "/delete/{timestamp}",method = RequestMethod.DELETE)
      public  String delDataByTimeStamp(@PathVariable("timestamp") Integer timestamp){
          int flag = allDataService.delete(timestamp);
          return (flag == 1 ?  "delete success!" : "delete fail!");
      }
  
      /**
       * 修改时间间隔信息
       * @param macAddress
       * @return
       *此部分由李朋恩同学完成
       */
      @RequestMapping(value = "/update",method = RequestMethod.PUT)
      public  String updateAllData(@RequestParam(value = "macAddress")String macAddress,
                                   @RequestParam(value = "updateInterval")Integer updateinterval){
          Integer tempInterval = intervalMap.get(macAddress);
          if(tempInterval != updateinterval)
          {
              intervalMap.remove(macAddress);
              intervalMap.put(macAddress,updateinterval);
          }
          String display = "macAddress:" + macAddress +"_updateInterval:_" + updateinterval.toString();
          return display;
      }
  
      /**
       * 新增信息
       * @param
       * @return
       *插入操作由李朋恩同学完成
       */
      @RequestMapping(value = "/add",method = RequestMethod.POST)
      public  Integer postAllData(@RequestBody AllData allData){
          //插入表equipment
          Equipment tempEquipment = new Equipment();
          tempEquipment.setMacAddress(allData.getMacAddress());
          tempEquipment.setRaspberryPiName(allData.getRaspberryPiName());
          int result = equipmentService.save(tempEquipment);
          //插入alldata表并返回时间间隔
          int t= allDataService.save(allData);
          String insertMacAddress = allData.getMacAddress();
          Integer insertInterval = allData.getUpdateInterval();
          if(intervalMap.get(insertMacAddress) == null) {
              intervalMap.put(insertMacAddress, insertInterval);
          }
          Integer nowInterval = intervalMap.get(insertMacAddress);
          
          //检验两个表是否都插入成功
          int s = result + t;
          return (s==2 ? nowInterval : 0);
      }
  
  } 
\end{lstlisting}

\section{AllDataDAO}
\begin{lstlisting}
  //此部分由伍思睿同学完成
  @Repository
public interface AllDataDAO extends MyBatisBaseDao<AllData, Integer> {

    List<AllData> selectAll();

    AllData selectByPrimaryKey(Integer timestamp);

    List<AllData> selectByMacAddress(String macAddress);

    List<AllData> selectByTimeBucket(@Param("startTime") String startTime,@Param("endTime") String endTime);

    int insert(AllData record);

    int insertSelective(AllData record);

    int deleteByPrimaryKey(Integer timestamp);

}
\end{lstlisting}

\section{EquipmentDAO}
\begin{lstlisting}
  //此部分由孙熙东同学完成
  @Repository("EquipmentDAO")
  public interface EquipmentDAO extends MyBatisBaseDao<Equipment, Integer> {
      List<Equipment> selectAll();
  
      int insert(Equipment equipment);
  
      Equipment selectByPrimaryKey(String macAddress);
  
  }
\end{lstlisting}

\section{MyBatisBaseDao}
\begin{lstlisting}
  //此部分由孙熙东同学完成
  public interface MyBatisBaseDao<Model, PK extends Serializable> {
    int deleteByPrimaryKey(PK id);

    int insert(Model record);

    int insertSelective(Model record);

    Model selectByPrimaryKey(PK id);

    int updateByPrimaryKeySelective(Model record);

    int updateByPrimaryKey(Model record);
}
\end{lstlisting}

\section{AllData}
\begin{lstlisting}
  //此部分由孙熙东同学完成初稿，伍思睿同学修改为小驼峰规范
  public class AllData implements Serializable {
    private Integer timestamp;

    private Integer numberOfSatellites;

    private String latitudeAndLongitude;

    private Integer battery;

    private String temperature;

    private String humidity;

    private String atmosphericPressure;

    private String macAddress;

    private String dateTime;

    private String raspberryPiName;

    private Integer updateInterval;

    private static final long serialVersionUID = 1L;

    public Integer getTimestamp() {
        return timestamp;
    }

    public void setTimestamp(Integer timestamp) {
        this.timestamp = timestamp;
    }

    public Integer getNumberOfSatellites() {
        return numberOfSatellites;
    }

    public void setNumberOfSatellites(Integer numberOfSatellites) {
        this.numberOfSatellites = numberOfSatellites;
    }

    public String getLatitudeAndLongitude() {
        return latitudeAndLongitude;
    }

    public void setLatitudeAndLongitude(String latitudeAndLongitude) {
        this.latitudeAndLongitude = latitudeAndLongitude;
    }

    public Integer getBattery() {
        return battery;
    }

    public void setBattery(Integer battery) {
        this.battery = battery;
    }

    public String getTemperature() {
        return temperature;
    }

    public void setTemperature(String temperature) {
        this.temperature = temperature;
    }

    public String getHumidity() {
        return humidity;
    }

    public void setHumidity(String humidity) {
        this.humidity = humidity;
    }

    public String getAtmosphericPressure() {
        return atmosphericPressure;
    }

    public void setAtmosphericPressure(String atmosphericPressure) {
        this.atmosphericPressure = atmosphericPressure;
    }

    public String getMacAddress() {
        return macAddress;
    }

    public void setMacAddress(String macAddress) {
        this.macAddress = macAddress;
    }

    public String getDateTime() {
        return dateTime;
    }

    public void setDateTime(String dateTime) {
        this.dateTime = dateTime;
    }

    public String getRaspberryPiName() {
        return raspberryPiName;
    }

    public void setRaspberryPiName(String raspberryPiName) {
        this.raspberryPiName = raspberryPiName;
    }

    public Integer getUpdateInterval() {
        return updateInterval;
    }

    public void setUpdateInterval(Integer updateInterval) {
        this.updateInterval = updateInterval;
    }

    @Override
    public boolean equals(Object that) {
        if (this == that) {
            return true;
        }
        if (that == null) {
            return false;
        }
        if (getClass() != that.getClass()) {
            return false;
        }
        AllData other = (AllData) that;
        return (this.getTimestamp() == null ? other.getTimestamp() == null : this.getTimestamp().equals(other.getTimestamp()))
                && (this.getNumberOfSatellites() == null ? other.getNumberOfSatellites() == null : this.getNumberOfSatellites().equals(other.getNumberOfSatellites()))
                && (this.getLatitudeAndLongitude() == null ? other.getLatitudeAndLongitude() == null : this.getLatitudeAndLongitude().equals(other.getLatitudeAndLongitude()))
                && (this.getBattery() == null ? other.getBattery() == null : this.getBattery().equals(other.getBattery()))
                && (this.getTemperature() == null ? other.getTemperature() == null : this.getTemperature().equals(other.getTemperature()))
                && (this.getHumidity() == null ? other.getHumidity() == null : this.getHumidity().equals(other.getHumidity()))
                && (this.getAtmosphericPressure() == null ? other.getAtmosphericPressure() == null : this.getAtmosphericPressure().equals(other.getAtmosphericPressure()))
                && (this.getMacAddress() == null ? other.getMacAddress() == null : this.getMacAddress().equals(other.getMacAddress()))
                && (this.getDateTime() == null ? other.getDateTime() == null : this.getDateTime().equals(other.getDateTime()))
                && (this.getRaspberryPiName() == null ? other.getRaspberryPiName() == null : this.getRaspberryPiName().equals(other.getRaspberryPiName()))
                && (this.getUpdateInterval() == null ? other.getUpdateInterval() == null : this.getUpdateInterval().equals(other.getUpdateInterval()));
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((getTimestamp() == null) ? 0 : getTimestamp().hashCode());
        result = prime * result + ((getNumberOfSatellites() == null) ? 0 : getNumberOfSatellites().hashCode());
        result = prime * result + ((getLatitudeAndLongitude() == null) ? 0 : getLatitudeAndLongitude().hashCode());
        result = prime * result + ((getBattery() == null) ? 0 : getBattery().hashCode());
        result = prime * result + ((getTemperature() == null) ? 0 : getTemperature().hashCode());
        result = prime * result + ((getHumidity() == null) ? 0 : getHumidity().hashCode());
        result = prime * result + ((getAtmosphericPressure() == null) ? 0 : getAtmosphericPressure().hashCode());
        result = prime * result + ((getMacAddress() == null) ? 0 : getMacAddress().hashCode());
        result = prime * result + ((getDateTime() == null) ? 0 : getDateTime().hashCode());
        result = prime * result + ((getRaspberryPiName() == null) ? 0 : getRaspberryPiName().hashCode());
        result = prime * result + ((getUpdateInterval() == null) ? 0 : getUpdateInterval().hashCode());
        return result;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(getClass().getSimpleName());
        sb.append(" [");
        sb.append("Hash = ").append(hashCode());
        sb.append(", timeStamp=").append(timestamp);
        sb.append(", numberOfSatellites=").append(numberOfSatellites);
        sb.append(", latitudeAndLongitude=").append(latitudeAndLongitude);
        sb.append(", battery=").append(battery);
        sb.append(", temperature=").append(temperature);
        sb.append(", humidity=").append(humidity);
        sb.append(", atmosphericPressure=").append(atmosphericPressure);
        sb.append(", macAddress=").append(macAddress);
        sb.append(", dateTime=").append(dateTime);
        sb.append(", raspberryPiName=").append(raspberryPiName);
        sb.append(", updateInterval=").append(updateInterval);
        sb.append(", serialVersionUID=").append(serialVersionUID);
        sb.append("]");
        return sb.toString();
    }
}
\end{lstlisting}

\section{Equipment}
\begin{lstlisting}
  //此部分由孙熙东同学完成
  public class Equipment {
    private  String macAddress;

    private  String raspberryPiName;

    public void setMacAddress(String macAddress) {
        this.macAddress = macAddress;
    }

    public void setRaspberryPiName(String raspberryPiName) {
        this.raspberryPiName = raspberryPiName;
    }

    public String getMacAddress() {
        return macAddress;
    }

    public String getRaspberryPiName() {
        return raspberryPiName;
    }

}
\end{lstlisting}

\section{AllDataService}
\begin{lstlisting}
  @Service
public class AllDataService {
    @Autowired
    AllDataDAO allDataDAO;
    public List<AllData> findAllDataList() {
        return allDataDAO.selectAll();
    }

    public AllData findAllDataByTimestamp(Integer timestamp) {
        return allDataDAO.selectByPrimaryKey(timestamp);
    }

    public List<AllData> findAllDataByMacAddress(String macAddress) {
        return allDataDAO.selectByMacAddress(macAddress);
    }


    //需要用到sql的where 大于小于
    public List<AllData> findAllDataByTimeBucket(String startTime, String endTime) {
        String tempStartTime = startTime.replace('_',' ');
        String tempEndTime = endTime.replace('_',' ');
        return allDataDAO.selectByTimeBucket(tempStartTime,tempEndTime);
    }

    //以此为界上半部分由孙熙东同学完成，下半部分由李朋恩与伍思睿同学完成
    public int delete(Integer timestamp) {
        return allDataDAO.deleteByPrimaryKey(timestamp);
    }

    public int save(AllData allData) {
    	Calendar c=Calendar.getInstance();
    	int seconds = allData.getTimestamp();
    	@SuppressWarnings("deprecation")
		long millions=new Long(seconds).longValue()*1000;
    	c.setTimeInMillis(millions);
    	System.out.println(""+c.getTime());
    	SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    	String dateString = sdf.format(c.getTime());
    	allData.setDateTime(dateString);
        return allDataDAO.insert(allData);
    }
}
\end{lstlisting}

\section{EquipmentService}
\begin{lstlisting}
  //此部分由孙熙东同学完成
  @Service
public class EquipmentService {
    @Autowired
    EquipmentDAO equipmentDAO;
    public List<Equipment> findEquipmentList() {
        return equipmentDAO.selectAll();
    }

    public Equipment findEquipment(String macAddress) {
        return equipmentDAO.selectByPrimaryKey(macAddress);
    }

    public int save(Equipment equipment) {
        return equipmentDAO.insert(equipment);
    }
}

\end{lstlisting}

\section{解决跨域问题}
\begin{lstlisting}
  @Configuration
public class CrosConfig extends WebMvcConfigurationSupport {
    //@Configuration:
    // Spring 容器在启动时，会加载默认的一些PostPRocessor，其中就有 ConfigurationClassPostProcessor，
    // 这个后置处理程序专门处理带有@Configuration注解的类，这个程序会在bean定义加载完成后，
    // 在bean初始化前进行处理。其主要处理的过程就是使用 cglib 动态代理对类进行增强，
    // 使用增强后的类替换了beanFactory原有的 beanClass，增强类会对其中带有@Bean注解的方法进行额外处理，
    // 确保调用带@Bean注解的方法返回的都是同一个实例。

    //跨域访问
    @Override
    protected void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowCredentials(true)
                .allowedHeaders("*")
                .allowedOrigins("*")
                .allowedMethods("*");
    }
}
\end{lstlisting}

\section{RaspberryPiDemobApplication}
\begin{lstlisting}
  @SpringBootApplication
  @MapperScan(" com.example.raspberry_pi_demob.DAO")
  public class RaspberryPiDemobApplication {
  
      public static void main(String[] args) {
          SpringApplication.run(RaspberryPiDemobApplication.class, args);
      }
  
  }
\end{lstlisting}

\section{allData.xml}
\begin{lstlisting}
  //此上半部分删除以前是孙熙东同学完成，包括删除以及以后的是由李朋恩同学完成
  <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.raspberry_pi_demob.DAO.AllDataDAO">
  <resultMap id="BaseResultMap" type="com.example.raspberry_pi_demob.entity.AllData">
    <id column="timestamp" jdbcType="INTEGER" property="timestamp" />
    <result column="numberOfSatellites" jdbcType="INTEGER" property="numberOfSatellites" />
    <result column="latitudeAndLongitude" jdbcType="VARCHAR" property="latitudeAndLongitude" />
    <result column="battery" jdbcType="INTEGER" property="battery" />
    <result column="temperature" jdbcType="VARCHAR" property="temperature" />
    <result column="humidity" jdbcType="VARCHAR" property="humidity" />
    <result column="atmosphericPressure" jdbcType="VARCHAR" property="atmosphericPressure" />
    <result column="macAddress" jdbcType="VARCHAR" property="macAddress" />
    <result column="dateTime" jdbcType="VARCHAR" property="dateTime" />
    <result column="raspberryPiName" jdbcType="VARCHAR" property="raspberryPiName" />
    <result column="updateInterval" jdbcType="INTEGER" property="updateInterval" />
  </resultMap>
  <sql id="Base_Column_List">
    `timestamp`, numberOfSatellites, latitudeAndLongitude, battery, temperature, humidity,
    atmosphericPressure, macAddress, `dateTime`, raspberryPiName, updateInterval
  </sql>

  <select id="selectAll" parameterType="java.lang.Integer" resultMap="BaseResultMap">
    select
    <include refid="Base_Column_List" />
    from  alldata
  </select>
  <select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
    select
    <include refid="Base_Column_List" />
    from alldata
    where `timestamp` = #{timestamp,jdbcType=INTEGER}
  </select>
  <select id="selectByMacAddress" parameterType="java.lang.String" resultMap="BaseResultMap">
    select *
    from  alldata
    where
    <if test="macAddress != null">
      `macAddress` = #{macAddress,jdbcType=VARCHAR}
    </if>
    <if test="timestamp != null">
      ORDER BY timestamp
    </if>
  </select>

  <select id="selectByTimeBucket" parameterType="java.lang.String" resultMap="BaseResultMap">
    select *
    from alldata
    where 1=1
    <if test="startTime != null and startTime !='' ">
      and `datetime` &gt;=  #{startTime,jdbcType=VARCHAR}
    </if>
    <if test="endTime != null and endTime !='' ">
      and `datetime` &lt;=  #{endTime,jdbcType=VARCHAR}
    </if>

  </select>


  <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
    delete from alldata
    where `timestamp` = #{timestamp,jdbcType=INTEGER}
  </delete>
  <insert id="insert" keyColumn="timestamp" keyProperty="timestamp" parameterType="com.example.raspberry_pi_demob.entity.AllData" useGeneratedKeys="true">
    insert into alldata (timestamp,numberOfSatellites, latitudeAndLongitude,
                         battery, temperature, humidity,
                         atmosphericPressure, macAddress, `dateTime`,
                         raspberryPiName, updateInterval)
    values (#{timestamp,jdbcType=INTEGER}, #{numberOfSatellites,jdbcType=INTEGER}, #{latitudeAndLongitude,jdbcType=VARCHAR},
            #{battery,jdbcType=INTEGER}, #{temperature,jdbcType=VARCHAR}, #{humidity,jdbcType=VARCHAR},
            #{atmosphericPressure,jdbcType=VARCHAR}, #{macAddress,jdbcType=VARCHAR}, #{dateTime,jdbcType=VARCHAR},
            #{raspberryPiName,jdbcType=VARCHAR}, #{updateInterval,jdbcType=INTEGER})
  </insert>
\end{lstlisting}

\section{equipment.xml}
\begin{lstlisting}
  //此部分由李朋恩同学完成，最后的插入ON DUPLICATE是由孙熙东同学添加
  <?xml version="1.0" encoding="UTF-8"?>
  <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  <mapper namespace="com.example.raspberry_pi_demob.DAO.EquipmentDAO">
      <resultMap id="BaseResultMap" type="com.example.raspberry_pi_demob.entity.Equipment">
          <id column="macAddress" jdbcType="VARCHAR" property="macAddress" />
          <result column="raspberryPiName" jdbcType="VARCHAR" property="raspberryPiName" />
      </resultMap>
      <sql id="Base_Column_List">
      macAddress, raspberryPiName
    </sql>
      <select id="selectAll" parameterType="java.lang.Integer" resultMap="BaseResultMap">
          select
          <include refid="Base_Column_List" />
          from  equipment
      </select>
      <select id="selectByPrimaryKey" parameterType="java.lang.String" resultMap="BaseResultMap">
          select
          <include refid="Base_Column_List" />
          from equipment
          where `macAddress` = #{macAddress,jdbcType=VARCHAR}
      </select>
      <insert id="insert" keyColumn="macAddress" keyProperty="macAddress" parameterType="com.example.raspberry_pi_demob.entity.Equipment" useGeneratedKeys="true">
      insert into equipment (macAddress, raspberryPiName)
      values (#{macAddress,jdbcType=VARCHAR},#{raspberryPiName,jdbcType=VARCHAR})
      ON DUPLICATE KEY UPDATE macAddress=macAddress
    </insert>
  
  </mapper>
\end{lstlisting}

\section{配置文件}
\begin{lstlisting}
  server:
  port: 8080

spring:
    datasource:
        name: test
        url: jdbc:mysql://127.0.0.1:3306/springweb?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8&useSSL=false&useInformationSchema=true&allowPublicKeyRetrieval=true
        username: root
        password: yours
        # 使用druid数据源
#        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        filters: stat
        maxActive: 20
        initialSize: 1
        maxWait: 60000
        minIdle: 1
        timeBetweenEvictionRunsMillis: 60000
        minEvictableIdleTimeMillis: 300000
        validationQuery: select 'x'
        testWhileIdle: true
        testOnBorrow: false
        testOnReturn: false
        poolPreparedStatements: true
        maxOpenPreparedStatements: 20

## 该配置节点为独立的节点，有很多同学容易将这个配置放在spring的节点下，导致配置无法被识别
mybatis:
  mapper-locations: classpath:mybatis/*.xml  #注意：一定要对应mapper映射xml文件的所在路径
  type-aliases-package: com.example.raspberry_pi_demob.entity  # 注意：对应实体类的路径

#pagehelper分页插件
pagehelper:
    helperDialect: mysql
    reasonable: true
    supportMethodsArguments: true
    params: count=countSql
\end{lstlisting}

\section{运行结果}
查询设备运行结果见 图 5-1，查询时间段内信息运行结果见 图 5-2，查询指定设备所有信息运行结果见 图 5-3，新增信息运行结果见 图 5-4，更改更新时间间隔运行结果见 图 5-5。
\begin{figure}[htbp]
  \centering
  \includegraphics[width=1\textwidth]{picture/getEq}
  \caption{查询设备图}\label{fig:getEq}
  \vspace{\baselineskip}
\end{figure}

\begin{figure}[htbp]
  \centering
  \includegraphics[width=1.2\textwidth]{picture/getTime}
  \caption{查询时间段内信息图}\label{fig:getTime}
  \vspace{\baselineskip}
\end{figure}

\begin{figure}[htbp]
  \centering
  \includegraphics[width=1.2\textwidth]{picture/getByMac}
  \caption{查询设备所有信息图}\label{fig:getByMac}
  \vspace{\baselineskip}
\end{figure}

\begin{figure}[htbp]
  \centering
  \includegraphics[width=0.9\textwidth]{picture/post}
  \caption{新增信息图}\label{fig:post}
  \vspace{\baselineskip}
\end{figure}

\begin{figure}[htbp]
  \centering
  \includegraphics[width=0.9\textwidth]{picture/putUpdate}
  \caption{更改更新时间图}\label{fig:putUpdate}
  \vspace{\baselineskip}
\end{figure}